#include "gu_renderer.h"
#include "gu_util.h"
#include "gu_uniform_map.h"

#include <GL/glew.h>

#include<cassert>

namespace gu{

/* OpenGL dummy renderer. */

/*Functions*/
#if 0
GLenum layoutToGlLayout(ElementLayout layout)
{
    GLenum result = 0;
    switch(layout)
    {
        case TRIANGLES: result = GL_TRIANGLES; break;
        case LINES: result = GL_LINES; break;
        case LINE_STRIP: result = GL_LINE_STRIP; break;
        case LINE_LOOP: result = GL_LINE_LOOP; break;
        default:assert(!"Faulty mapping!");break;
    }
    return result;
}
#endif

class DummyRenderer : public Renderer
{
public:

    DummyRenderer(ShaderDialect dialect = GLSL_330):
        uniformMap_(newUniformMap(dialect)),
        streamMap_(newStreamMap(dialect)),
        applyStateSequence_(state::getApply(dialect))
    {}
/*
    void materialSlot(MaterialSlot* material) override {material_ = material;}
    MaterialSlot* materialSlot() override{return material_;}
*/
    ShaderAdapter getShaderAdapter() override
    {
        return ShaderAdapter(uniformMap_.get(), streamMap_.get());
    }

    void applyState(state::DataSequence& dataSequence) override 
    {
        applyStateSequence_(dataSequence);
    }

#if 0 // return only shader adapter bound to these!
    UniformMap* uniformMap() override {return uniformMap_;}
    StreamMap*  streamMap() override {return streamMap_.;}
#endif

#if 0
    bool render() override
    {
        auto indexBuffer = mesh_->indexBuffer();
        auto vertexBuffer = mesh_->vertexBuffer();
        auto layout = layoutToGlLayout(indexBuffer->layout());
        auto indexCount = indexBuffer->indexCount();
        mesh_->use();
        glDrawElements(layout, indexCount, GL_UNSIGNED_SHORT, 0);
        guCheckGlError("drawBuffer");
        return true;
    }
#endif
/*
    bool render() override
    {
        bool result = false;
        if(material_)
        {
            result = true;
            material_->render();
        }
        guCheckGlError("drawBuffer");
        return result;
    }
*/

// Will add stuff to manage buffer state, clear (clearing done by renderer.clear() ?, renderer.clearColor() ? etc)

private:
    std::unique_ptr<UniformMap> uniformMap_;
    std::unique_ptr<StreamMap> streamMap_;

    state::ApplyFunction applyStateSequence_;
};

Renderer* newRenderer()
{
    return dynamic_cast<Renderer*>(new DummyRenderer());
}

}// namespace gu
